package com.yao.mymvc.handleradapter;

import com.yao.mymvc.annotation.ResponseBody;
import com.yao.mymvc.handleradapter.iface.HandlerAdapter;
import com.yao.mymvc.handlermapping.HandlerMethod;
import com.yao.mymvc.utils.JsonUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 将RequestMappingHandlerAdapter适配成HandlerAdapter
 *
 * @author Henry Yao
 * @date 2021/5/2
 */
public class RequestMappingHandlerAdapter implements HandlerAdapter {
    /**
     * 具体的处理逻辑
     *
     * @param handler  处理器类
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    public ModelAndView handleRequest(Object handler, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 将handler转成HandlerMethod类型
        Object h = ((HandlerMethod) handler).getHandler();
        Method m = ((HandlerMethod) handler).getMethod();
        // 处理url可能带有的参数
        Object[] args = getParameter(request, m);
        // 取出HandlerMethod对象中的方法执行返回结果
        Object returnValue = m.invoke(h, args);
        handleReturnValue(returnValue, m, response);
        return null;
    }

    private void handleReturnValue(Object returnValue, Method m, HttpServletResponse response) throws IOException {
        // 判断方法是否使用@ResponseBody修饰
        if (m.isAnnotationPresent(ResponseBody.class)) {
            response.setContentType("text/plain;charset=utf8");
            response.getWriter().write(returnValue.toString());
        } else if (returnValue instanceof Map) {
            response.setContentType("application/json;charset=utf8");
            response.getWriter().write(JsonUtils.object2Json(returnValue));
        } else {
            //todo 其他处理
        }

    }

    private Object[] getParameter(HttpServletRequest request, Method method) {
        List<Object> params = new ArrayList<>();
        // 获取所有的参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        // 获取方法的所有参数
        Parameter[] parameters = method.getParameters();
        for (Parameter p : parameters) {
            // 获取参数类型
            String name = p.getName();
            Class<?> type = p.getType();
            String[] strings = parameterMap.get(name);
            Object value = convertValue(strings, type);
            params.add(value);
        }
        return params.toArray();
    }

    private Object convertValue(String[] strings, Class<?> type) {
        if (type == List.class) {
            return strings;
        } else if (type == Integer.class) {
            return Integer.parseInt(strings[0]);
        } else if (type == String.class) {
            return strings[0];
        } else {
            //todo 处理其他类型
            return null;
        }
    }

    @Override
    public boolean supports(Object handler) {
        return handler instanceof HandlerMethod;
    }
}
